|
|
Greetings, Raytracers!
I recently discovered a cute technique for scenes that use lots of copies of
a few similar mesh objects, for example, plants.
The problem is that if you only use a small number of mesh objects, this can
be obvious on close inspection. However, if you use too many different
meshes, then you start to lose the memory advantage that meshes give you.
My trick is to make meshes that can be overlapped on top of each other. The
simplest way to do this is to use a checker pattern. Given a pair of meshes
that can be overlapped thusly, we can create 16 different variations by
using the 8 symmetry transforms of the square. So, with just 8 base mesh
objects, we can make 256 mesh pairs. This definitely helps to disguise the
fact that the meshes are being reused. :)
Anyway, here's a simple scene to illustrate the technique. I'll post a scene
file of a patch of turf in p.b.i.
//-----------------------------------------------------------------------------
// Persistence of Vision Ray Tracer Scene Description File
// File: MultiMesh.pov
// Vers: 3.6
// Desc: Overlapping mesh test
// Date: 27 Aug 2005
// Auth: PM 2Ring
//
// Inspired by:
//
// From: Mike Williams
// Subject: Re: Optimizing scenes with nested loops.
// Date: 13 Aug 2005 05:50:19
// Message: <mfea4CA4nY$CFwvC@econym.demon.co.uk>
//
// -f -A0.6 +AM2 +R1
// -d +A0.1 +AM2 +R3
//
#version 3.6;
#include "colors.inc"
#include "transforms.inc"
global_settings {
assumed_gamma 1.0
}
//scene element control
#declare subCount = 4; //MUST be even!
#declare patchCount = 4;
//randomizer macros
#declare R2 = seed(17);
#macro RI(A) floor(A*rand(R2)) #end //Random integer between 0 &
<A
//-----------------------------------------------------------------------------
//Convert UV coordinates to hue & thence to RGB
#macro GetColour(U,V)
#local H = 720*(floor(V/2)+floor(U/2)/subCount)/subCount;
CHSV2RGB(<H, 1, 1>)
#end
// Create a square pyramid as a 'sub-mesh'. Transform by Trans, pointwise.
#macro MakePyramid(Pig, Trans)
//Pyramid vertices
#local Apex = vtransform(y, Trans);
#local Base = array[4]{-x, z, x, -z};
#local I = 0;
#while (I < 4)
#local Base[I] = vtransform(Base[I], Trans);
#local I = I + 1;
#end
#local T1 = texture{pigment{Pig}finish{specular .5}transform Trans}
//Make pyramid sides
#local I = 0;
#while (I < 4)
triangle {
Apex, Base[I], Base[mod(I+1,4)]
texture {T1}
}
#local I = I + 1;
#end
#end
//make a patch of 'sub-meshes' as a single mesh, in a checkered layout,
//so patches can be overlapped pairwise
#macro MakePatch(F)
mesh{
#local I=0;
#while(I < subCount)
#local J=mod(I, 2);
#while(J < subCount)
//Create submesh transform
#local Trans = transform{
rotate 45*y
scale sqrt(.5)/subCount
translate (<J, 0, I> - .5*<1, 0, 1>*(subCount-1))/subCount
}
//Create submesh pigment
#local C = GetColour((F?I:subCount-1-J), (F?J:I));
#local CMap = colour_map{[.4 C][.5 rgb F][.6 C]}
#local Pig = pigment{radial frequency 4 colour_map{CMap}}
//#local Pig = pigment{bozo scale 1/subCount colour_map{CMap}}
//#local Pig = C;
MakePyramid(Pig, Trans)
#local J = J + 2;
#end
#local I = I + 1;
#end
scale subCount/(1+subCount)
}
#end
//Create 2 patches
#declare patchM = 2;
#declare Patch = array[patchM];
#declare Patch[0] = MakePatch(0);
#declare Patch[1] = MakePatch(1);
//The group of transforms of a square. 'Even' transforms first.
#declare SqTrans = array[8]
{
transform{}, // 0 ... I
transform{rotate 90*y scale <-1, 1, 1>}, // 5 R.X RX
transform{rotate 90*y scale < 1, 1,-1>}, // 6 RZ. RZ
transform{rotate 180*y}, // 3 .ZX R^2
transform{rotate 90*y}, // 4 R.. R
transform{scale <-1, 1, 1>}, // 1 ..X X
transform{scale < 1, 1,-1>}, // 2 .Z. Z
transform{rotate -90*y}, // 7 RZX R^3
}
//---Scene-----------------------------------
//place overlapping pairs of patches
#if(1 & (patchCount = 4)) //show all combinations
union {
#declare I=0;
#while(I < patchCount)
#declare J=0;
#while(J < patchCount)
object {
Patch[0]
transform SqTrans[I] //do an even transform
translate <I, 0, J>
}
object {
Patch[1]
transform SqTrans[J+4] //do an odd transform
translate <I, 0, J>
}
#declare J = J + 1;
#end
#declare I = I + 1;
#end
translate -0.5*<1, 0, 1>*(patchCount-1)
}
#else //show random combinations
union {
#declare I=0;
#while(I < patchCount)
#declare J=0;
#while(J < patchCount)
object {
Patch[RI(patchM)]
transform SqTrans[RI(4)] //do an even transform
translate <I, 0, J>
}
object {
Patch[RI(patchM)]
transform SqTrans[RI(4)+4] //do an odd transform
translate <I, 0, J>
}
#declare J = J + 1;
#end
#declare I = I + 1;
#end
translate -0.5*<1, 0, 1>*(patchCount-1)
}
#end
background{rgb .5}
//camera {location patchCount*<-1, 2, -3>*.52 look_at .3*y angle 40}
//forward
camera {orthographic location y*patchCount*2.5 look_at 0 angle 30}
//overhead
light_source {<10, 40, -20> rgb 1}
//-----------------------------------------------------------------------------
Post a reply to this message
|
|